﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;


namespace TrayTool
{
  public partial class TrayTool : Form
  {
    private Container Components = new Container();
    private NotifyIcon NotifyIcon = new NotifyIcon();
    private ContextMenu TrayMenu = new ContextMenu();
    private UserActivityHook Hook = new UserActivityHook(false, false);
    private List<ToolStripMenuItem> HiddenWindows = new List<ToolStripMenuItem>();


    public TrayTool() : base()
    {
      SuspendLayout();

      Visible = false;
      Disposed += (s, e) => Components.Dispose();
      ContextMenuStrip = TrayMenu;

      NotifyIcon.ContextMenuStrip = TrayMenu;
      NotifyIcon.Icon = Resources.TrayToolIcon;
      NotifyIcon.Text = "TrayTool";
      NotifyIcon.Visible = true;
      Components.Add(NotifyIcon);

      TrayMenu.HideClick += (s, e) => Hook.Start(true, false);
      Components.Add(TrayMenu);

      Hook.MouseActivity += HideClickHandler;
      Hook.KeyPress += HotkeyHandler;

      ResumeLayout();
      WindowsAPI.RegisterHotKey(Handle, GetType().GetHashCode(), WindowsAPI.MOD_WIN, Keys.OemPeriod);
    }


    ~TrayTool()
    {
      WindowsAPI.UnregisterHotKey(Handle, GetType().GetHashCode());
    }


    protected override void WndProc(ref Message m)
    {
      switch (m.Msg)
      {
        case WindowsAPI.WM_HOTKEY:
          Hook.Start(false, true);
          break;
      }
      base.WndProc(ref m);
    }

    /// <summary>
    /// Overridden to prevent the form from becoming visible.
    /// </summary>
    protected override void SetVisibleCore(bool value)
    {
    }

    private void HideClickHandler(object sender, MouseEventArgs e)
    {
      if (ContextMenuStrip.Visible && e.Button != MouseButtons.None)
      {
        Hook.Stop();
        if (!ContextMenuStrip.Bounds.Contains(e.Location))
        {
          ContextMenuStrip.Visible = false;
        }
      }
      else if (e.Button == MouseButtons.Left)
      {
        Hook.Stop();

        IntPtr handle = WindowsAPI.GetAncestor(WindowsAPI.WindowFromPoint(new Point(e.X, e.Y)), WindowsAPI.GA_ROOTOWNER);
        if (handle != WindowsAPI.GetDesktopWindow())
        {
          StringBuilder sb = new StringBuilder(256);
          WindowsAPI.GetWindowText(handle, sb, sb.MaxCapacity);

          ToolStripMenuItem item = new ToolStripMenuItem();
          item.Text = sb.ToString();
          item.Click += (o, a) => item.Dispose();
          item.Disposed += (o, a) => WindowsAPI.ShowWindow(handle, WindowsAPI.ShowWindowCmd.Show);
          item.Disposed += (o, a) => TrayMenu.Remove(item);
          item.Disposed += (o, a) => HiddenWindows.Remove(item);
          TrayMenu.Add(item);
          HiddenWindows.Add(item);

          WindowsAPI.ShowWindow(handle, WindowsAPI.ShowWindowCmd.Hide);
        }
      }
    }

    private void HotkeyHandler(object sender, KeyPressEventArgs e)
    {
      Hook.Stop(false, true, false);

      switch (Char.ToUpper(e.KeyChar))
      {
        case 'X':
          Application.Exit();
          break;

        case 'I':
          NotifyIcon.Visible = !NotifyIcon.Visible;
          break;

        case 'S':
          ContextMenuStrip.Visible = !ContextMenuStrip.Visible;
          if (ContextMenuStrip.Visible)
          {
            Hook.Start(true, false);
          }
          break;

        case 'H':
          Hook.Start(true, false);
          break;

        case 'A':
          foreach (ToolStripMenuItem item in HiddenWindows.ToArray())
          {
            item.PerformClick();
          }
          break;

        default:
          return;
      }

      e.Handled = true;
    }
  }
}
